package com.cars.util.json;

import com.cars.util.date.DateUtil;
import com.cars.util.global.GlobalReturnCode;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * JSON工具类，进行对象转string和string转对象
 */
public class JsonUtil {
    private static ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 把对象转成json串
     *
     * @param obj 对象，可以是VO、List、HashMap等等
     * @return 返回生成的json值
     */
    public static String toStr(Object obj) {
        String json_str = "";
        try {
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            objectMapper.setDateFormat(new SimpleDateFormat(DateUtil.defaultTimeFormatStr));
            json_str = objectMapper.writer().writeValueAsString(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json_str;
    }

    /**
     * 把对象转成json串
     *
     * @param obj        对象，可以是VO、List、HashMap等等
     * @param dateFormat 日期格式
     * @return 返回生成的json值
     */
    public static String toStr(Object obj, String dateFormat) {
        String json_str = "";
        try {
            objectMapper.setDateFormat(new SimpleDateFormat(dateFormat));
            json_str = objectMapper.writer().writeValueAsString(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json_str;
    }

    /**
     * json转对象
     *
     * @param jsonStr   json字符串
     * @param valueType 要转成的对象类型，采用泛型的方式
     * @return
     */
    public static <T> T toObject(String jsonStr, Class<T> valueType) {
        try {
            return objectMapper.readValue(jsonStr, valueType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * json转对象
     *
     * @param jsonStr    json字符串
     * @param valueType  要转成的对象类型，采用泛型的方式
     * @param dateFormat 日期格式
     * @return
     */
    public static <T> T toObject(String jsonStr, Class<T> valueType, String dateFormat) {
        try {
            objectMapper.setDateFormat(new SimpleDateFormat(dateFormat));
            return objectMapper.readValue(jsonStr, valueType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * json转List
     *
     * @param json     json字符串
     * @param javaType 要转成的对象类型，采用泛型的方式
     * @return 转成的List对象
     */
    public static <T> List<T> toArray(String json, JavaType javaType) {
        try {
            return (List<T>) objectMapper.readValue(json, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param json
     * @param valueType
     * @param <T>
     * @return
     */
    public static <T> List<T> toArray(String json, Class<T> valueType) {
        try {
            JavaType javaType = getCollectionType(ArrayList.class, valueType);
            return (List<T>) objectMapper.readValue(json, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 直接读取json串里面某个节点的值
     *
     * @param json    json字符串
     * @param nodeStr 节点名
     * @return json的节点
     */
    public static Object getNode(String json, String nodeStr) {
        String str = "";
        try {
            str = objectMapper.readTree(json).get(nodeStr).toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 直接读取json串里面某个节点的值
     *
     * @param json    json字符串
     * @param nodeStr 节点名
     * @return json的节点
     */
    public static JsonNode getJsonNode(String json, String nodeStr) {
        JsonNode node = null;
        try {
            node = objectMapper.readTree(json).get(nodeStr);
        } catch (Exception e) {
//            e.printStackTrace();
        }
        return node;
    }

    public static String getNodeStr(String json, String nodeStr) {
        String str = "";
        try {
            str = objectMapper.readTree(json).get(nodeStr).textValue();
        } catch (Exception e) {
            System.out.println("json格式错误" + json);
        }
        return str;
    }

    /**
     * 返回json的jsonNode
     *
     * @param json
     * @return
     */
    public static JsonNode getNode(String json) {
        JsonNode jsonNode = null;
        try {
            jsonNode = objectMapper.readTree(json);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonNode;
    }


    /**
     * 把json转成map
     *
     * @param jsonStr
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static Map toMap(String jsonStr) {
        Map map = new HashMap();
        try {
            map = objectMapper.readValue(jsonStr, Map.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 将json串转换成hashMap
     *
     * @param json json串
     * @return
     */
    public static HashMap<String, String> toHashmap(String json) {
        HashMap<String, String> hashMap = toObject(json, HashMap.class);
        return hashMap;
    }

    /**
     * 直接获取响应的对象
     * <p>
     * 注意return
     *
     * @param json      请求响应JSON串
     * @param valueType 对应对象的Class
     * @param <T>       对应对象
     * @return 如果响应失败返回null，需要进一步获取响应失败原因； 如果响应成功直接返回对应对象
     */
    public static <T> T getReturnData(String json, Class<T> valueType) {
        JsonResult jsonResult = toObject(json, JsonResult.class);
        if (jsonResult == null
                || !GlobalReturnCode.OK.getReturnCode().equals(jsonResult.getReturnCode())) {
            return null;
        }
        return toObject(toStr(jsonResult.getData()), valueType);
    }

    /**
     * 反序列化生成对象
     *
     * @param collectionClass
     * @param elementClasses
     * @return
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * 解析jsonNode的值
     *
     * @param node
     * @param attrs "aa.bb.cc"
     * @return
     */
    public static String getJsonNodeValue(JsonNode node, String attrs) {
        int index = attrs.indexOf('.');
        if (index == -1) {
            if (node != null && node.get(attrs) != null) {
                return node.get(attrs).textValue();
            }
            return "";
        } else {
            String s1 = attrs.substring(0, index);
            String s2 = attrs.substring(index + 1);
            return getJsonNodeValue(node.get(s1), s2);
        }
    }

    public static void main(String[] args) throws Exception {
//        User user = new User();
//        user.setId(1);
//        user.setName("张三");
//        user.setDate(new Date());
////        System.out.println(JsonUtil.toStr(user));
////        System.out.println(JsonUtil.toStr(user, "yyyy-MM-dd"));
//        String json = "{\"id\":1,\"name\":\"张三\",\"date\":\"2020-06-01 11:59:14\"}";
////        System.out.println(JsonUtil.toObject(json, User.class));
////        System.out.println(JsonUtil.toObject(json, User.class, "yyyy-MM-dd"));
////        System.out.println(JsonUtil.getNode(json, "date"));
//
//        List<User> list = new ArrayList<>();
//        list.add(user);
//        String json2 = "[{\"id\":1,\"name\":\"张三\",\"date\":\"2020-06-01 11:59:14\"}]";
//        List<User> lst = JsonUtil.toArray(json2, User.class);
////        System.out.println(lst);
//
//        System.out.println(JsonUtil.toMap(json));
    }
}
